package gitobject;

import repository.Repository;
import zlib.ZLibUtils;

import java.io.*;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class JitIndex implements Serializable {

    private static final long serialVersionUID = -3643313826959884015L;
    private final Map<String, String> indexMap;
    private final Map<String, Integer> statusMap;
    public static Integer added = 1;
    public static Integer modified = 2;
    public static Integer newFile = 3;
    public static Integer untracked = 4;

    private static final String indexPath = Repository.getGitDir() + File.separator + "index";
    public JitIndex(){
        indexMap = new TreeMap<>();
        statusMap = new TreeMap<>();
    }

    public Map<String, String> getIndexMap(){ return indexMap; }
    public boolean contains(String key){ return indexMap.containsKey(key); }
    public void putIndex(String file, String content){ indexMap.put(file, content); }
    public String getIndex(String keyPath){ return indexMap.get(keyPath); }
    public String getIndexKey(String keyPath){
        String indexContent = indexMap.get(keyPath);
        if(indexContent != null){
            String[] line = indexContent.split("\\s+");
            return line[2];
        }
        else return null;
    }
    public void clearIndex(){ indexMap.clear(); }
    public Set<Map.Entry<String, String>> getMapValues(){ return indexMap.entrySet(); }
    public boolean removeIndex(String file){
        if(indexMap.containsKey(file)){
            indexMap.remove(file);
            return true;
        }
        else
            return false;
    }

    //public Map<String, Integer> getStatusMap(){ return statusMap; }
    public boolean containsStatus(String keyPath) { return statusMap.containsKey(keyPath); }
    public void putStatus(String keyPath, Integer status){ statusMap.put(keyPath, status); }
    public Integer getStatus(String keyPath){ return statusMap.get(keyPath); }
    public void clearStatus(){ statusMap.clear(); }
    public Set<Map.Entry<String, Integer>> getStatusValues(){ return statusMap.entrySet(); }
    public boolean removeStatus(String keyPath){
        if(statusMap.containsKey(keyPath)){
            statusMap.remove(keyPath);
            return true;
        }
        else
            return false;
    }

    public boolean compressWrite() throws Exception{
        /**
         * Add your code here.
         */
        if(new File(Repository.getGitDir()).exists()) {
            OutputStream os = new FileOutputStream(indexPath);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ObjectOutputStream file = new ObjectOutputStream(out);
            file.writeObject(this);
            file.flush();
            byte[] bytes = out.toByteArray();
            ZLibUtils.compress(bytes, os);
            return true;
        }
        else{
            System.out.println("fatal: not a jit repository: .jit");
            return false;
        }
    }

    public static JitIndex deserialize(){
        File indexFile = new File(indexPath);
        if(!indexFile.exists()){
            JitIndex newJitIndex = new JitIndex();
            try {
                newJitIndex.compressWrite();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return newJitIndex;
        }
        JitIndex indexObject = null;
        try {
            ByteArrayInputStream in = new ByteArrayInputStream(deCompress());
            ObjectInputStream file = new ObjectInputStream(in);
            indexObject = (JitIndex) file.readObject();
            file.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return indexObject;
    }

    public static byte[] deCompress() throws IOException{
        File object = new File(indexPath);
        if(!object.exists())
            System.out.printf("fatal: Not a valid index name %s\r\n", indexPath);
        InputStream is = new FileInputStream(object);
        return ZLibUtils.decompress(is);
    }
}
